﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SQLite;
using System.Collections;

namespace ufolder
{
    public partial class StructForm : Form
    {
        private SQLiteConnection connection;

        public delegate void TagStrucModifiedDelegate();
        public delegate void TagDoubleClickedDelegate(string label);

        public StructForm()
        {
            InitializeComponent();
        }

        public void InitTagDisplay(SQLiteConnection c)
        {
            this.connection = c;
            this.InitTagDisplay();
        }
       
        public event TagStrucModifiedDelegate TagStructModified;
        public event TagDoubleClickedDelegate TagDoubleClicked;

        public void InitTagDisplay()
        {
            contextMenuStrip.Close();
            tSCBAddGrpTag.Items.Clear();
            tSCBRen.Items.Clear();
            this.treeView.Nodes.Clear();
            

            string sql = "SELECT id, label from tags ORDER BY label";
            SQLiteCommand command = new SQLiteCommand(sql, this.connection);
            SQLiteCommand command2 = null;
            SQLiteDataReader dr = null;
            SQLiteDataReader dr2 = null;

            try
            {
               // command.Transaction = this.connection.BeginTransaction();
                dr = command.ExecuteReader();

                while (dr.Read())
                {
                    string Level1 = dr["label"].ToString();
                    string sqlNbrItem = "SELECT COUNT(items_b.id) FROM items_b INNER JOIN items_tags ON (items_b.id = items_tags.item_id) WHERE items_tags.tag_id = " + dr["id"].ToString(); ;
                    string sql2 = "SELECT tags.label FROM edges INNER JOIN tags ON (edges.startvertex = tags.id) WHERE edges.endvertex = " + dr["id"].ToString() + " AND edges.hops = 0 ORDER BY label";

                    command2 = new SQLiteCommand(sqlNbrItem, this.connection);

                    int nbrItem = int.Parse(command2.ExecuteScalar().ToString());

                    command2.CommandText = sql2;

                    dr2 = command2.ExecuteReader();
                    ArrayList al = new ArrayList();

                    while (dr2.Read())
                    {
                        al.Add(new TreeNode(dr2["label"].ToString()));
                    }
                    dr2.Dispose();


                    TreeNode tn = new TreeNode(dr["label"].ToString() + " [" + nbrItem + "]", (TreeNode[])al.ToArray(typeof(TreeNode)));

                    this.treeView.Nodes.Add(tn);
                    tSCBAddGrpTag.Items.Add(dr["label"].ToString());
                    tSCBRen.Items.Add(dr["label"].ToString());
                }
                dr.Dispose();
                //command.Transaction.Commit();
            }
            catch (SQLiteException ex)
            {
                if (dr != null) dr.Dispose();
                if (dr2 != null) dr2.Dispose();
                command.Transaction.Rollback();
                System.Windows.Forms.MessageBox.Show(ex.Message, "Erreur", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
            finally
            {
                if (command != null) command.Dispose();
                if (command2 != null) command2.Dispose();
            }
        }

        private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            tSMRenTag.Enabled = tSMDelTag.Enabled = tSMAddGroupTag.Enabled = (treeView.SelectedNode != null);
            tSMRemGrpTag.Enabled = (treeView.SelectedNode.Parent != null);
        }

        private void tSCBAddGrpTag_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r' && tSCBAddGrpTag.Text!="" && Label.CheckValidTag(tSCBAddGrpTag.Text))
            {
                Label lToAdd = new Label(tSCBAddGrpTag.Text, this.connection);
                string sN = treeView.SelectedNode.Text;
                sN=sN.Substring(0, sN.LastIndexOf(' '));
                Label lRoot = new Label(sN , this.connection);
                lRoot.AddLabel(lToAdd, this.connection);
                this.InitTagDisplay();
                if (TagStructModified != null) TagStructModified();
            }
        }

        private void tSMRemGrpTag_Click(object sender, EventArgs e)
        {
            if (treeView.SelectedNode.Parent != null)
            {
                string sN = treeView.SelectedNode.Text;
                if (sN.LastIndexOf(' ') > 0) sN = sN.Substring(0, sN.LastIndexOf(' '));

                string sNParent = treeView.SelectedNode.Parent.Text;
                sNParent = sNParent.Substring(0, sNParent.LastIndexOf(' '));

                Label lToRemove = new Label(sN, this.connection);
                Label lParent = new Label(sNParent, this.connection);
                lParent.RemoveLabel(lToRemove, this.connection);
                this.InitTagDisplay();
                if (TagStructModified != null) TagStructModified();
            }
        }

        private void tSCTagAdd_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r' && tSCTagAdd.Text != "" && Label.CheckValidTag(tSCTagAdd.Text))
            {
                Label l = new Label(tSCTagAdd.Text.ToLower(), this.connection);
                this.InitTagDisplay();
            }
        }

        private void tSMDelTag_Click(object sender, EventArgs e)
        {
            string sN = treeView.SelectedNode.Text;
            if (sN.LastIndexOf(' ') > 0) sN = sN.Substring(0, sN.LastIndexOf(' '));

            Label l = new Label(sN, this.connection);
            treeView.DrawNode -= treeView_DrawNode;

            l.Delete(this.connection);
            this.InitTagDisplay();

            treeView.DrawNode += treeView_DrawNode;
            if (TagStructModified != null) TagStructModified();
        }

        private void tSCBRen_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r' && tSCBRen.Text!="")
            {
                string sN = treeView.SelectedNode.Text;
                if (sN.LastIndexOf(' ') > 0) sN = sN.Substring(0, sN.LastIndexOf(' '));

                if (tSCBRen.Text != sN)
                {
                    Label lToRen = new Label(sN, this.connection);


                    lToRen.Rename(tSCBRen.Text);
                    this.InitTagDisplay();
                    if (TagStructModified != null) TagStructModified();
                }
            }
        }

        private void treeView_DoubleClick(object sender, EventArgs e)
        {
            if (treeView.SelectedNode != null)
            {
                string sN = treeView.SelectedNode.Text;
                if (sN.LastIndexOf(' ') > 0) sN = sN.Substring(0, sN.LastIndexOf(' '));

                if (TagDoubleClicked != null) TagDoubleClicked(sN);
            }
        }

        private void contextMenuStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e)
        {
            tSCTagAdd.Text = tSCBRen.Text = tSCBAddGrpTag.Text = "";
        }

        private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            if (e.Node.IsVisible)
            {
                string sN = e.Node.Text;
                if (sN.LastIndexOf(' ') > 0) sN = sN.Substring(0, sN.LastIndexOf(' '));

                e.Graphics.FillRectangle(new SolidBrush(Label.GetColorFromLabel(sN, connection)), e.Node.Bounds);

                // Retrieve the node font. If the node font has not been set,
                // use the TreeView font.
                Font nodeFont = e.Node.NodeFont;
                if (nodeFont == null) nodeFont = ((TreeView)sender).Font;

                // Draw the node text.
                e.Graphics.DrawString(e.Node.Text, nodeFont, Brushes.Black, e.Bounds);


                // If the node has focus, draw the focus rectangle large, making
                // it large enough to include the text of the node tag, if present.
                if ((e.State & TreeNodeStates.Focused) != 0)
                {
                    using (Pen focusPen = new Pen(Color.Black))
                    {
                        focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                        Rectangle focusBounds = e.Node.Bounds;
                        focusBounds.Size = new Size(focusBounds.Width - 1, focusBounds.Height - 1);
                        e.Graphics.DrawRectangle(focusPen, focusBounds);
                    }
                }
            }
            
        }
    }
}
